let Ast;
(function() {
	/*文法定义
	<程序>::=  {<语句>}
	<语句>::= <变量定义>|<赋值>|<输出>|<函数定义>|<函数执行>|<判断>|<循环>
	<变量定义>::= "dim"<变量>;
	<赋值>::= <变量>:=<表达式>;
	<输出>::= "print""("<表达式>")";
	<表达式>::= <项>{<加减><项>}
	<项>::=<因子>{<乘除><因子>}
	<因子>::=<变量>|<数字>|<执行函数>|"-"<因子>|"("<表达式>")"
	<判断>::="if""("<条件组>")"{"<程序>"}["else"{"<程序>"}"]
	<循环>::="while""("<条件组>")""{"<程序>"}"
	<条件组>::=<条件>{[逻辑符号]<条件>}
	<条件>::=<表达式>[比较]<表达式>
	<函数定义>::= "fun"变量"("<变量组>")""{"<程序>return<表达式>;"}"
	<执行函数>::=<变量>"("<表达式组>")"
	<变量组>::=<变量>{,<变量组>}
	<表达式组>::=<表达式>{,<表达式>}
	*/
   let tokens =[]
   let index = -1
   function getToken(){
	   if(index>=tokens.length-1) {
		   return 'END'
	   }
	  return tokens[++index] 
   }
   function consoleErr(msg){
	   var m = msg?msg:''
	   throw Error(tokens[index -1].value + '附近有语法错误;'+ m)
   }
   function dim(){
	   let _ast = {
		   type:'dim',
		   name:''
	   }
	    let token = getToken()
		if(token.value!=='dim') {
			consoleErr()
		}
		token = getToken()
		if(token.type!=='variable'){
			consoleErr('变量格式为字母开头字母数字组合')
		}
		_ast.name = token.value
		token = getToken()
		if(token.value!==';'){
			consoleErr('缺少;')
		}
		return _ast
   }
   function variable(){
	   let _ast = []
	   let token = getToken()
	   if(token.type!=='variable') {
		   consoleErr('变量格式为字母开头字母数字组合')
	   }
	   _ast.push({
		   type:'variable',
		   name:token.value
	   })
	   token = getToken()
	   while(token.value === ','){
		   index--
		   token = getToken()
		   if(token.value!==','){
			  consoleErr() 
		   }
		   token = getToken()
		   if(token.type!=='variable'){
		   	  consoleErr('变量格式为字母开头字母数字组合') 
		   }  
		   _ast.push({
			   type:'variable',
			   name:token.value
		   })
			token = getToken()
	   }
	   index --
	   return _ast
   }
   function funcall(){
	   let _ast = {
	   		   type:'funcall',
	   		   name:'',
	   		   parameter:[]
	   }
	   let token = getToken()
	   if(token.type!=='variable'){
	   	consoleErr('变量格式为字母开头字母数字组合')
	   }
	   _ast.name = token.value
	   token = getToken()
	   if(token.value!=='('){
	   	consoleErr()
	   }else{
		   token = getToken()
		   if(token.value!==')'){
		   	 index --
		   	 _ast.parameter = expression_group()
			 token = getToken()
			  if(token.value!==')'){
				 consoleErr('缺少)') 
			  }
			}
	   }
	   return _ast
   }
   function fun(){
	   let _ast = {
		   type:'fun',
		   name:'',
		   parameter:[],
		   body:'',
		   'return':''
	   }
	   let token = getToken()
	   if(token.value!=='fun'){
	   	consoleErr()
	   }
	   token = getToken()
	   if(token.type!=='variable'){
	   	consoleErr('函数名必须为字母开头字母数字组合')
	   }
	   _ast.name = token.value
	   token = getToken()
	   if(token.value!=='('){
	   	consoleErr('缺少(')
	   }
	   token = getToken()
	   if(token.value!==')'){
	   	 index --
		 _ast.parameter = variable()
		 token = getToken()
		  if(token.value!==')'){
			 consoleErr('缺少)') 
		  }
	   }
	   token = getToken()
	   if(token.value!=='{'){
	   	consoleErr('缺少{')
	   }
	    _ast.body = program()
		token = getToken()
		if(token.value!=='return'){
			consoleErr('函数以return返回值结尾')
		}
		_ast['return'] = expression()
		token = getToken()
		if(token.value!==';'){
			consoleErr('缺少;')
		}
		token = getToken()
	   if(token.value!=='}'){
	   	consoleErr('缺少}')
	   }
	   return _ast
   }
   function print(){
	   let _ast={
		   type:'print'
	   }
	   let token = getToken()
	   if(token.value!=='print') {
		  consoleErr() 
	   }
	   token = getToken()
	   if(token.value!=='(') {
	   		consoleErr('缺少(') 
	   }
	   _ast.value = expression()
	   token = getToken()
	   if(token.value!==')') {
	   		consoleErr('缺少)') 
	   }
	   token = getToken()
	   if(token.value!==';') {
	   		consoleErr('缺少;') 
	   }
	   return _ast
   
   }
   function loop(){
	   let _ast={
		   
	   }
	   let token = getToken()
	   if(token.value!=='while') {
	   		consoleErr(token) 
	   }
	   _ast.type ="while"
	   token = getToken()
	   if(token.value!=='(') {
	   		  consoleErr('缺少(') 
	   }
	   _ast.condition = condition_group()
	   token = getToken()
	   if(token.value!==')') {
	   		  consoleErr('缺少)') 
	   }
	   token = getToken()
	   if(token.value!=='{') {
	   		  consoleErr('缺少{') 
	   }
	   _ast.body=program()
	   token = getToken()
	   if(token.value!=='}') {
	   		  consoleErr('缺少}') 
	   }
	   return _ast
   }
   function condition_group(){
	   let _ast
	  let token;
	   _ast=condition()
	   token = getToken()
	   while(token.value=='and'||token.value=='or') {
		  let _newAst = {
			   type:'condition',
			   left:_ast,
			   operator:token.value,
			   right:condition()
		   }
		   _ast = _newAst
		   token = getToken()
	   }
	   index --
	   return _ast
   }
   function condition(){
	    let _ast;
	    let token;
		_ast = {
			type:'condition',
			left:expression()
		}
		token = getToken()
		if(token.value!=='='&&token.value!=='>='&&token.value!=='<='&&token.value!=='<'&&token.value!=='>'&&token.value!=='!=') {
			consoleErr('不是比较运算符') 
		}
		_ast.operator = token.value
		_ast.right = expression()
		return _ast
   }
   function expression(){
	   let _ast = item()
	   token = getToken()
	   if(token.value === '+'||token.value === '-') {
		 while(token.value === '+'||token.value === '-'){
			  let _newAst = {
				  type:'expression',
				  left:_ast,
				  operator:token.value,
				  right:item() 
			  }
			  _ast = _newAst
			 token = getToken()
	     }
	   } 
	   index --
	   return _ast
   }
   function item(){
	   let _ast = factor()
	   token = getToken()
	   if(token.value === '*'||token.value === '/') {
		   while(token.value === '*'||token.value === '/'){
			   let _newAst = {
				  type:'expression',
				  left:_ast,
				  operator:token.value,
				  right:factor()  
			   }
			   _ast = _newAst
			   token = getToken()
		   }
	   }
	   index --
	   return _ast
   }
   function factor(){
	    let token = getToken()
		let _ast
		if(token.type==='variable'){
			let nextToken = getToken()
			if(nextToken.value=='('){
				index -=2
				_ast = funcall()
			}else {
				_ast = token
				index--
				//终结
			}
		}else if(token.type==='number'){
			_ast = {
				type:token.type,
				value:parseFloat(token.value)
			}
			// 终结
		}else if(token.value==='('){
			_ast = expression()
			token = getToken()
			if(token.value!==')') {
				consoleErr('缺少)')
			}
		}else if(token.value==='-'){
			_ast= {
				type:'expression',
				left:0,
				operator:'-',
				righy:factor()
			}
		}else{
			consoleErr('表达式错误')
		}
	 return _ast
   }
   function expression_group(){
	   let _ast= []
	   _ast.push(expression())
	   token = getToken()
	   while(token.value===','){
		  _ast.push(expression())
		  token = getToken()
	   }
	   index --
	   return _ast
   }
   function judge(){
	   let _ast = {
		   type:'if'
	   };
	   let token = getToken()
	   if(token.value!=='if') {
	   		  consoleErr() 
	   }
	   token = getToken()
	   if(token.value!=='(') {
	   		  consoleErr('缺少(') 
	   }
	   _ast.condition = condition_group()
	   token = getToken()
	   if(token.value!==')') {
	   		  consoleErr('缺少)') 
	   }
	   token = getToken()
	   if(token.value!=='{') {
	   		  consoleErr('缺少{') 
	   }
	   _ast.body = program()
	   token = getToken()
	   if(token.value!=='}') {
	   		  consoleErr('缺少}') 
	   }
	   token = getToken() 
	   if(token.value!=='else') {
	   		index --
	   }else {
	   	token = getToken()
	   	if(token.value!=='{') {
	   	    consoleErr('缺少{') 
	   	}
	   	_ast.elsebody = program()
	   	token = getToken()
	   	if(token.value!=='}') {
	   		consoleErr('缺少}') 
	   	}
	   }
	   return _ast
   }
   function assign(ast){
	   let _ast = {
		   type:'assign',
		   variable:'',
		   value:''
	   }
	   let token = getToken()
	   if(token.type!=='variable'){
		  consoleErr('变量格式为字母开头字母数字组合')
	   }
	   _ast.variable = token.value
	   token = getToken()
	   if(token.value!==':='){
	   	  consoleErr('缺少赋值运算符:=')
	   }
	   _ast.value = expression()
	   token = getToken()
	   if(token.value!==';'){
	   	consoleErr('缺少;')
	   }
	   return _ast
   }
   function program(ast){
	   let token = getToken()
	   let _ast = []
	   while(token !== 'END') {
		   if(token.value === 'dim'){
			   index--
			   //变量定义		   
			   _ast.push(dim())
		   }else if(token.type==='variable') {
			   let nextToken = getToken()
			   if(token.value==='(') {
				   index-=2  
				   //函数执行
				   _ast.push(funcall())
			   }else {
				 index-=2
				  //赋值
				 _ast.push(assign())
			   }
		   }else if(token.value==='print') {
			   //输出
			   index--
			   _ast.push(print())
		   }else if(token.value==='fun') {
			   //函数定义
			   index--
			   _ast.push(fun())
		   }else if(token.value==='if') {
			   index--
			   _ast.push(judge())
		   }else if(token.value==='while') {
			   index--
			   _ast.push(loop())
		   }else {
			   index--
			   break			   
		   }
		   token = getToken()
	   }
	   return _ast
   }
   Ast = function(token){
	   tokens = token
	   index = -1
	   return program()
   }
})()
